package com.cskaoyan.javase.oop2._0encapsulate;

/**
 * 封装的基本理解
 * 封装（encapsulate）是指将数据及相关操作绑定在一起的一种编程机制，使其构成一个不可分割的独立实体。在Java中，类就是这样一种结构。当然，数据被保护在类的内部，是为了尽可能地隐藏内部的细节，只保留一些对外"接口"使之与外部发生联系。
 * 这里的接口不是java语法中的接口,而是一个广泛意义上的接口,是提供给外界访问内部的工具或者手段.
 *
 * 之所以要封装，是为了将代码的使用者和实现者分开。使用者能够完全得到自己想要的功能，又不需要思考过多细节；实现者可以隐藏功能实现的细节，方便灵活进行修改而不影响使用者使用。
 *
 * 以上,说明Java语法中的封装是依赖于访问权限修饰符来实现的.
 * 所以狭义的封装,在java中指私有化成员变量,然后必要的手段(方法)来与外界进行交互.
 * 私有化成员变量后,一般是让外部绝对无法访问.但是即便外界有访问需求,仍然建议私有化成员变量,然后提供相应的方法给外界使用.
 *      如果外界想要访问,那就提供访问的方法,称之为"Getter"方法
 *      语法格式:
 *          public 成员变量的数据类型 getXxx(){
 *              return 成员变量名;
 *          }
 *     如果外界想要进行赋值操作,那就提供赋值的方法,称之为"Setter"方法
 *     语法格式:
 *          public void setXxx(成员变量的数据类型 成员变量名){
 *              this.成员变量名 = 成员变量名;
 *          }
 *
 * 为什么不用对象名点访问成员变量,为什么非要写getter/setter方法?
 *      1.用方法可以控制访问和赋值,这是对象名点访问做不到的.
 *      2.用方法以后,成员变量的访问和赋值分开操做了
 *
 * 注意事项:
 *      1.成员变量的访问权限应该尽量收紧，尽量私有化，当然有必要时也可以给外界权限直接访问。
 *      2.Getter/Setter方法都有固定的格式,实际上完全没必要手写,自动生成即可
 *          alt + insert
 *          当然在开发中,不要无脑生成Getter/Setter方法,要思考哪些该写,哪些不该写
 *      3.静态成员变量如果有需要写Getter/Setter方法,那么它们也应该是static修饰的静态成员方法
 *          当然静态成员变量一般不需要Getter/Setter方法
 *          因为它本身就是类全局唯一
 *          如果外界想要访问,直接给权限就行了!
 *
 * @since 17:11
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        // System.out.println(s.age);
        System.out.println(s.getAge());

        s.setAge(90);
        System.out.println(s.getAge());

        s.setAge(500);
        System.out.println(s.getAge());
    }
}

class Student {
    // 隐藏实现细节,不希望外界直接访问年龄
    private int age;

    private String name;
    private double score;
    private int id;
    private String gender;

    public String getName() {
        return name;
    }

    // public void setName(String name) {
    //     this.name = name;
    // }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    // 外界访问age的方法
    public int getAge() {
        return age;
    }

    // 外界赋值age的方法
    public void setAge(int age) {
        if (age > 120 || age < 0) {
            System.out.println("不可能,绝对不可能!");
            return;
        }
        this.age = age;
    }
}
